package com.xt.wikiperfumapi.Controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xt.wikiperfumapi.model.UserInfo;
import com.xt.wikiperfumapi.model.dto.LoginRequest;
import com.xt.wikiperfumapi.model.dto.OneData;
import com.xt.wikiperfumapi.model.vo.RestBean;
import com.xt.wikiperfumapi.service.impl.UserInfoServiceImpl;
import com.xt.wikiperfumapi.util.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author 24862
 */
@RestController
@RequestMapping("api/auth")
@Slf4j
public class UserLoginController {

    @Resource
    JwtUtil jwtUtil;

    @Resource
    AuthenticationManager authenticationManager;


    @Resource
    PasswordEncoder passwordEncoder;

    @Resource
    JedisUtil jedisUtil;

    @Resource
    GenerationAccountUtil generationAccountUtil;

    @Resource
    UserInfoServiceImpl userInfoService;


    @Resource
    IdWorkerUtils idWorkerUtils;


    @Resource
    RandomCodeGenerator generator;

    @Value("${user.headerImg}")
    String  userImg;

    /**
     * 携带参数Json
     * {
     * "username":"poxiaodi",
     * "password":"poxiaodi"
     * }
     */
    @PostMapping("login")
    public RestBean doLogin(@RequestBody LoginRequest request) {
        try {
            UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(request.getUsername()
                    , request.getPassword());
            Authentication authentication = authenticationManager.authenticate(auth);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            UserInfo info = userInfoService.getOne(new QueryWrapper<UserInfo>()
                    .eq("username", userDetails.getUsername()));
            String jwtToken = jwtUtil.getToken(info.getUserPk());//通过uuid来jwt生成获取token
            String userUUID = info.getUserPk();
            jedisUtil.setNewVal(2, userUUID, jwtToken);//通过userId来存储
            return RestBean.success(jwtToken);//返回jwt
        } catch (Exception e) {
            log.error(e.getMessage());
            log.error("username or password is not correct");
            return RestBean.failure(401, "登录失败");
        }
    }


    @RequestMapping("/updateTime")
    public RestBean updateUserUpdateTime(HttpServletRequest request){
        String uuid = jwtUtil.getJwtUUID(request);
        UserInfo byId = userInfoService.getById(uuid);
        byId.setUpdateTime(new Date());
        return userInfoService.updateById(byId)?RestBean.success(byId)
                :RestBean.failure(500,"server error");
    }

    //更新用户信息
//    @RequestMapping("/updateUserInfo")
//    public RestBean updateUserInfo(@RequestBody UserInfo userInfo,HttpServletRequest request){
//        String uuid = jwtUtil.getJwtUUID(request);
//        UserInfo byId = userInfoService.getById(uuid);
//        if(userInfo.getName() != null &&  !userInfo.getName().isEmpty()){
//            byId.setName(userInfo.getName());
//        }
//        if (userInfo.getTel()!= null &&  !userInfo.getTel().isEmpty())
//            byId.setTel(userInfo.getTel());
//        if(userInfo.getMail()!=null &&  !userInfo.getMail().isEmpty())
//                byId.setMail(userInfo.getMail());
//        byId.setSex(userInfo.getSex());
//        byId.setAge(userInfo.getAge());
//        byId.setIsPerfumeWork(userInfo.getIsPerfumeWork());
//        byId.s(userInfo.getWorkStatusFk());
//        byId.setUserStatusFk(userInfo.getUserStatusFk());
//        if(userInfo.getBornDate()!=null &&  !userInfo.getBornDate().toString().isEmpty())
//            byId.setBornDate(userInfo.getBornDate());
//        if(userInfo.getProvince() !=null)
//            byId.setPrivilege(userInfo.getProvince());
//        if(userInfo.getCity() != null)
//            byId.setCity(userInfo.getCity());
//        byId.setUpdateTime(new Date());
//        return userInfoService.updateById(byId)?
//                RestBean.success(byId):
//                RestBean.failure(500,"server error");
//    }



    @RequestMapping("updateImg")
    public RestBean updateUserImg(@RequestBody OneData oneData, HttpServletRequest request){
        String uuid = jwtUtil.getJwtUUID(request);
        UserInfo byId = userInfoService.getById(uuid);
        byId.setHeadimgurl(oneData.getData().toString());
        byId.setUpdateTime(new Date());
        return userInfoService.updateById(byId)?
                RestBean.success(byId):RestBean.failure(500,"server error");
    }


    /**
     * 传递参数包含
     * {
     * "username":"test233",
     * "password":"test",
     * "email":"test",
     * "role":"admin",
     * "account":"",
     * "demo":"",
     * "address":"",
     * "bornDate":"2023-10-04",
     * "img":"",
     * "qqNum":"",
     * "wxNum":"",
     * "sex":"男"
     * }
     * <p>
     * {
     * username,
     * password,
     * email,
     * roles
     * }
     *
     * @param user
     * @return
     */

    @PostMapping("/register")
    public RestBean userRegister(@RequestBody UserInfo user, @RequestParam String code) {
        if (user.getMail() == null || user.getMail().isEmpty()
                || user.getPassword() == null || user.getPassword().isEmpty()) {
            return RestBean.failure(401, "用户名或密码不能为空");
        }else if (code.isEmpty()) {
            return RestBean.failure(401, "验证码不能为空");
        }
        String password = passwordEncoder.encode(user.getPassword());
        //存储数据库中的密码要进行加密处理
        user.setPassword(password);
        long userCount = userInfoService.count(new QueryWrapper<UserInfo>()
                .eq("username", user.getMail()));   //用户名不可重复,email作为用户登录账号
        if (userCount == 0L) {
            try {
                String qrCode = jedisUtil.getValue(6, user.getMail());
                if (qrCode.equals(code)) {
                    if (!(user.getRoles().equals("user") || user.getRoles().equals("shop"))) {
                        return RestBean.failure(403, "角色权限分配错误");
                    }
                    UUID uuid = UUID.randomUUID();
                    user.setUserPk(String.valueOf(uuid));//UUID生成唯一标识
                    user.setInputTime(new Date());
                    user.setUsername(user.getMail());
                    //这里将redis里面的进行读取 进行验证码操作
                    user.setHeadimgurl(userImg);
                    if (user.getName() == null || user.getName().isEmpty()) {
                        user.setName(generationAccountUtil.generation("用户"));
                    }//生成昵称
                    if(userInfoService.save(user)){
                        log.info(user.toString());
                        String jwtToken = jwtUtil.getToken(user.getUserPk());//这里也采用uuid返回jwt
                        jedisUtil.setNewVal(2, user.getUserPk(), jwtToken);//通过userId来存储
                        return RestBean.success(jwtToken);
                    }
                    return RestBean.failure(500,"server error");
                } else {
                    return RestBean.failure(403, "验证码错误");
                }
            } catch (Exception e) {
                log.info(e.getMessage());
            }
        } else {
            log.info("Username:" + user.getUsername() + "is exists");
            return RestBean.failure(403, "该邮箱已被注册，请重新换绑邮箱，或者重置密码试试？");
        }
        return RestBean.failure(403, "注册失败");
    }

    @RequestMapping("update/user")
    public RestBean updateUserInfoByUserSelf(@RequestBody UserInfo userLoginInfo
            , HttpServletRequest httpServletRequest) {
        log.info(userLoginInfo.toString());
        try {
            String uuid = jwtUtil.getJwtUUID(httpServletRequest);//获取uuid
            log.info(uuid);
            long count = userInfoService.count(new QueryWrapper<UserInfo>()
                    .eq("user_pk", uuid)
                    .eq("is_enable", 1)
                    .eq("is_delete", 0)
            );

            if (count == 1) {//用来查看是否存在该用户
                UserInfo info = userInfoService.getById(uuid);//通过请求人的uuid来获取
                userLoginInfo.setUpdateTime(new Date());//设置更新时间
                userLoginInfo.setUserPk(uuid);//来获取jwt里面的uuid
                userLoginInfo.setPassword(info.getPassword());//这里不能直接修改密码，修改密码到必须专门的接口来修改
                userLoginInfo.setInputTime(info.getInputTime());//账号创建时间不可修改
                userLoginInfo.setMail(info.getMail());//邮箱地址也不可以从这里修改
                userLoginInfo.setIsEnabled(info.getIsEnabled());//账号状态不可从这里修改,有专门的接口来进行初始化操作。
//                userLoginInfo.setRoles(info.getRoles());//角色信息不可以修改，后续可以完善，比如商家版本
                userLoginInfo.setUsername(info.getUsername());//用户账号必须通过专门的接口写，不可以直接更改，防重
                userLoginInfo.setIsDeleted(info.getIsDeleted());//用户是否注销
                //密码、邮箱、账号、余额都必须专门的接口来写，不可以直接修改
                //查看是否存在该用户设置的用户名，或者该人就是这个用户名
                boolean updateById = userInfoService.updateById(userLoginInfo);
                if (updateById) {
                    return RestBean.success(userLoginInfo, 1L);
                }
                return RestBean.failure(500, "更新失败");
            } else {
                return RestBean.failure(403, "token error | user is unEnable");//不存在该uuid
            }
        } catch (Exception e) {
            log.info(e.getMessage());
            return RestBean.failure(500, "更新用户信息失败");
        }
    }

    @RequestMapping("/charge/name")
    public RestBean chargeUsername(HttpServletRequest request,String  username){
        String uuid = jwtUtil.getJwtUUID(request);
        long count = userInfoService.count(new QueryWrapper<UserInfo>()
                .eq("username", username)
        );
        if (count > 0){
            return RestBean.failure(400,"该账号已重复，请更换其他的账号名试试");
        }
        UserInfo info = userInfoService.getById(uuid);
        info.setUsername(username);
        info.setUpdateTime(new Date());
        if (userInfoService.updateById(info)) {
            return RestBean.success(info);
        }
        return RestBean.failure(500,"更新账号失败");
    }

//    @RequestMapping("/password/forget")
    public RestBean updateByEmail(@RequestBody LoginRequest request, String code) throws Exception {
        UserInfo userLoginInfo = userInfoService.getOne(new QueryWrapper<UserInfo>()
                .eq("username", request.getUsername()));
        if (userLoginInfo != null) {
            if (jedisUtil.exist(4, userLoginInfo.getMail())) {
                if (jedisUtil.getValue(4, userLoginInfo.getMail()).equals(code)) {
                    userLoginInfo.setPassword(passwordEncoder.encode(request.getPassword()));//更新密码
                    userLoginInfo.setUpdateTime(new Date());//更新时间
                    return userInfoService.updateById(userLoginInfo)
                            ? RestBean.success(jwtUtil.getToken(request.getUsername()), 1L)
                            : RestBean.failure(500, "更新失败");
                }
                return RestBean.failure(403, "验证码错误");
            }
            return RestBean.failure(403, "请重新获取验证码");
        }
        return RestBean.failure(403, "没有该用户");
    }


//    @RequestMapping("update/admin")//要返回该用户的uuid
    public RestBean updateUserInfoByAdmin(@RequestBody UserInfo userLoginInfo) {
        try {
            boolean flag = false;//定义一个标识符来查看是否存在该用户的uuid
            List<UserInfo> userLoginInfos = userInfoService.list();
            for (UserInfo loginInfo : userLoginInfos) {
                if (loginInfo.getUsername().equals(userLoginInfo.getUsername())) {
                    return RestBean.failure(403, "用户名已存在");
                }
                if (userLoginInfo.getUserPk().equals(loginInfo.getUserPk())) {
                    flag = true;
                }
            }//查看用户名是否存在
            if (flag && (userInfoService.updateById(userLoginInfo))) {//如果更新成功那么返回
                return RestBean.success(userInfoService.getById(userLoginInfo.getUserPk()), 1L);
            }
            return RestBean.failure(500, "更新失败");
        } catch (Exception e) {
            log.info(e.getMessage());
            return RestBean.failure(500, "更新用户信息失败");
        }
    }

//    @RequestMapping("charge/email")
    public RestBean chargeEmail(HttpServletRequest request,String  code,String email){
        String uuid = jwtUtil.getJwtUUID(request);
        UserInfo info = userInfoService.getById(uuid);
        if (code.equals(jedisUtil.getValue(5, email))){
            info.setMail(email);
            info.setUpdateTime(new Date());
            if (userInfoService.updateById(info)){
                return RestBean.success(info);
            }
            return RestBean.failure(500,"更新失败");
        }
        return RestBean.failure(400,"验证码错误");
    }

    @PostMapping("check")//更新登陆状态，如果已经过时，那么需要重新登陆
    public RestBean checkRepeat(HttpServletRequest httpServletRequest) throws Exception {
        String uuid = jwtUtil.getJwtUUID(httpServletRequest);
        log.info(uuid);
        if (uuid == null) {
            return RestBean.failure(403, "请重新登录");
        }
        UserInfo info = userInfoService.getOne(new QueryWrapper<UserInfo>().eq("user_pk", uuid));
        if (info == null) {
            return RestBean.failure(403, "没有此用户");
        }
        String userId = info.getUserPk();
        if (jedisUtil.exist(2, userId)) {
            String token = jwtUtil.getToken(uuid);
            jedisUtil.setNewValExpire(2, userId, token, 60 * 60 * 24 * 7);
            return RestBean.success(token, 1L);
        } else {
            return RestBean.failure(403, "登录已过期");
        }
    }


    @RequestMapping("/userinfo")
    public RestBean getUserInfo(HttpServletRequest request) {
        String uuid = jwtUtil.getJwtUUID(request);
        if (uuid == null) {
            return RestBean.failure(500, "没有此用户");
        }
        long count = userInfoService.count(new QueryWrapper<UserInfo>()
                .eq("user_pk", uuid)
        );
        if (count == 0L) {
            return RestBean.failure(403, "没有此用户");
        }
        UserInfo info = userInfoService.getById(uuid);
        String userId = info.getUserPk();
        if (jedisUtil.exist(2, userId)) {
            return RestBean.success(info);
        } else {
            return RestBean.failure(403, "登录已过期");
        }
    }

    @RequestMapping("test")
    public String test(String name,HttpServletRequest request) {
        System.out.println(request.getRemoteHost());
        System.out.println(request.getRemoteAddr());
        System.out.println(request.toString());
        return "hello world"+name;
    }

    @RequestMapping("/get-userinfo")
    public RestBean getUserInfoById(String userId){
        long count = userInfoService.count(new QueryWrapper<UserInfo>()
                .eq("user_pk", userId)
        );
        if (count == 0L){
            return RestBean.failure(400,"不存在该用户");
        }
        return RestBean.success(userInfoService.getById(userId));
    }

    @RequestMapping("/initPassword/{id}")
    public RestBean initPassword(String email,@PathVariable int id){
        try {
            if(jedisUtil.getValueTTL(3,email) > 0){
                UserInfo userInfo = userInfoService.getOne(new QueryWrapper<UserInfo>()
                        .eq("username", email)
                );
                int i = id == 1 ? 6 : id == 2? 8 : 12;
                String randomCode = generator.generateRandomCode(i);
                userInfo.setPassword(passwordEncoder.encode(randomCode));
                return userInfoService.updateById(userInfo)?
                        RestBean.success("电子邮箱"+email+"成功，请妥善保管密码,刷新可以重新获取随机密码："
                                +randomCode):RestBean.failure(500,"server error");
            }else{
                return RestBean.failure(400,"已超时，请重新获取邮箱");
            }
        }catch (Exception e){
            log.info(e.getMessage());
            return RestBean.failure(400,"没有此人账户");
        }
    }

    @RequestMapping("/isShop")
    public RestBean isShopRoles(HttpServletRequest request){
        String uuid = jwtUtil.getJwtUUID(request);
        try {
            UserInfo byId = userInfoService.getById(uuid);
            if(byId.getIsDeleted() == 0){
                if (!byId.getRoles().equals("shop")){
                    return RestBean.failure(400,"用户角色权限异常");
                }
                String token = jwtUtil.getToken(uuid);
                return RestBean.success(token);
            }
            return RestBean.failure(400,"该账户已被禁用");
        }catch (Exception e){
            return RestBean.failure(400,"不存在该账户");
        }

    }

}
